package displayboardinfo.services;

import java.util.Iterator;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBElement;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.sun.jersey.api.client.ClientResponse.Status;

import displayboardinfo.entities.Admission;
import displayboardinfo.entities.Room;
import displayboardinfo.entities.User;
import displayboardinfo.utils.LogicalException;

/**
 * Klasa odpowiedzialna za wystawianie usług związanych z logowaniem użytkowników.
 * 
 * @author Artur Jaworski
 */
@Path("/login")
public class LoginServices {
	/**
	 * Usługa logowania użytkownika do systemu.
	 * Usługa dostępna jest na serwerze pod adresem /login używając metody POST.
	 * Usługa zwraca kod 200 [OK] gdy wywołanie się powiedzie lub kod 406 [NOT ACCEPTABLE] gdy wystąpi błąd (niepoprawne dane logowania, błąd serwera).
	 * Przy wystąpieniu błędu do odpowiedzi dołączany jest krótki opis przyczyny błędu.
	 * 
	 * @param userJaxb obiekt reprezentujący użytkownika logującego się do systemu z uzupełnionymi polami login i password, w formie koperty XML
	 * @return obiekt użytkownika uzupełniony o wszystkie informacje zawarte w bazie danych (imię, nazwisko, typ) 
	 */
	@SuppressWarnings({ "deprecation", "rawtypes" })
	@POST
	@Consumes(MediaType.APPLICATION_XML)
	@Produces(MediaType.APPLICATION_XML)
	public User login(JAXBElement<User> userJaxb) {
		User user = userJaxb.getValue();
		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		Session session = sf.openSession();
		
		try {
			Query query = session.createQuery("from User as u where u.login = :login").setParameter("login", user.getLogin());
			User userDb = null;
			for (Iterator it = query.iterate(); it.hasNext();) {
				Object item = it.next();

				userDb = (User) item;
			}
			
			if (userDb == null || !userDb.getPassword().equals(user.getPassword()))
				throw new LogicalException("Zły login lub hasło");
			
			User response = new User();
			response.setId(userDb.getId());
			response.setLogin(userDb.getLogin());
			response.setName(userDb.getName());
			response.setSurname(userDb.getSurname());
			response.setUserType(userDb.getUserType());
			for (Admission a : userDb.getAdmissions()){
				a.setUser(null);
				a.getRoom().setAdmissions(null);
				a.getRoom().setRegisteredForUpdates(null);
				a.getRoom().setUsers(null);
				a.getRoom().setVisits(null);
			}
			for (Room r : userDb.getRooms()){
				r.setUsers(null);
				r.setRegisteredForUpdates(null);
				r.setVisits(null);
				r.setAdmissions(null);
			}
			response.setAdmissions(userDb.getAdmissions());
			response.setRooms(userDb.getRooms());
			
			return response;
			
		} catch (LogicalException e){
			throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build());
		} catch (Exception e) {
			throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE).entity("Nieokreślony błąd").type(MediaType.TEXT_PLAIN).build());
		} finally {
			session.close();
			sf.close();
		}
	}
	
}
